他の記事を見てみる
Jul 25 2018 / 22:42:54
プログラミング > webアプリ開発 >
Keyword:

共用サーバーで非同期通信チャットアプリを作る

執筆者ホームページ

𝖢𝗋𝖾𝖺𝗍𝗂𝗏𝖾 𝖦𝖯

皆さん久しぶりです、CreativeGPと申します。

今日は、さくらサーバーのライトプランという制限が多いサーバーでなんとか非同期通信を実現すべく奮闘したので、その記録をしたいと思います。

作ったチャットアプリ Chatterソースコード

非同期通信、双方向通信

馴染みのある同期通信は、普段ブラウザがやっているようにURLを指定して、サーバーにアクセスして、サーバーからデータを取得して其れで終わりです。

しかし、非同期なWebサービスを作ろうと思ったときには時に特殊な通信方法を取らなければならないと思います。つまり、前述した同期通信だけでは実現しにくい処理ですね。

また、クライアントがサーバーに行ってデータを取ってくる、ということは良くありますが、その逆の通信も馴染みがありません。

色々な方法がある

さて、この非同期通信や双方向通信を行う方法ですが、本当に色々な方法があるようです。(需要が昔からあったため昔から色々な方法が模索されてきた

AJAX

馴染みがあるやつですね。JavaScriptを使用して非同期通信を実現します。

WebRTC

Web上でP2Pでリアルタイムな通信を行うための規格群です。最初はこれを使って色々作ろうと思っていましたが、自分のサーバーでは動かない(常在プロセスを作らなければならない)ということを知り、断念しました。

WebSocket

WebSocketは非同期で双方向通信をすることが出来る、とても便利なHTTPと同じレベルのプロトコルです。これはとても使い勝手が良く、コードも書き易かったのですが、これも自分のサーバーでは動かないことを知り、断念しました。

Commet

ここからは、如何にしてサーバーからクライアントに情報を送るかということにフォーカスした技術を紹介します。これはちょっと昔に使われていた(今は上のやつで代替できるため)やつらしいですが、HTTPで実現できます。アイデアは長く通信を保っておくということです。

クライアントはサーバーにリクエストを送ります。しかし、サーバーはクライアントにすぐレスポンスを返しません。イベントが起きた時に返すのです。こうすることによってプロトコルを変えずにゴニョゴニョすることができます。

しかし問題点もたくさんあります。例えば、サーバーがイベントを返して、また次のためにクライアントがレスポンスをサーバーに返す時にまたイベントが発生した場合にサーバーはクライアントに情報を伝えるすべがなく、ラグが生じてしまう、という問題があります。

EventSource

今回使ったのはこれです。これはHTTPで非同期・Server->Client通信が出来るもので、仕様はW3Cによって定められており(Server-Sent Events)、専用のJavaScriptのAPIが用意されています。見た所他の技術より静かと言うか、情報も比較的少ないですし、活気がないような気がしました。しクライアントの実装も問題があったところがあったとか無かったとかで若干心配なこともありますが、これを使うことによってやっと共用サーバーでもリッチな通信をすることが出来るようになりました。

情報がないと言っても、優れた記事が何個かあるかつ、仕様も短く、シンプルなので簡単に実装できると思います†‡ので、記事を載せておくだけにします。

Server Sent Events最小限のサンプル(PHP)

EventSource 覚え書き - JavaScriptで遊ぶよ - g:javascript

この二つと、先程の仕様(短いので!)

Server-Sent Events

を見れば完璧だと思います。

† そのままだと駄目なので、サーバーからなんか言われると、クライアントはまた次のイベントを取得できるように準備するためレスポンスを投げます。

†‡ 少なくともWebRTCよりは(STUN/TURNとか置かなきゃだし)